package com.cf.invoker.http.server;

import com.cf.invoker.HttpInvokerConstant;
import com.cf.mapper.BeanMapper;
import com.cf.util.ObjectJsonUtil;
import com.cf.util.RequestUtil;
import com.cf.util.SpringBeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @author Ricky Fung
 */
@Slf4j
public class InvokHandlerServlet extends HttpServlet {

    private ServiceRegisterStore serviceRegisterStore;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
        RequestUtil.renderJson(resp, "调用不支持get操作，请使用post");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String serviceKey = req.getParameter(HttpInvokerConstant.SERVICR_KEY);
        ServiceMeta methodMeta = serviceRegisterStore.getMethod(serviceKey);
        String argues = req.getParameter(HttpInvokerConstant.ARGUES);
        try {
            Object invokeResult = methodMeta.getMethod().invoke(methodMeta.getMethodParentBean(), parseArgues(argues, methodMeta.getArgumentTypes()));
            RequestUtil.renderJson(resp, invokeResult);
        } catch (Exception e) {
            log.error("服务调用出现错误！", e);
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            RequestUtil.renderJson(resp, "server error" + e.getMessage());
        }
    }

    private Object[] parseArgues(String argues, List<Class<?>> argumentTypes) {
        if (argumentTypes == null) {
            return new Object[0];
        }
        List<String> arguesString = ObjectJsonUtil.toListObject(argues, String.class);
        if (argumentTypes.size() != arguesString.size()) {
            throw new IllegalArgumentException("服务端参数不匹配！");
        }
        Object[] objects = new Object[arguesString.size()];
        for (int i = 0; i < arguesString.size(); i++) {
            objects[i] = ObjectJsonUtil.toObject(arguesString.get(i), argumentTypes.get(i));
        }
        return objects;
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        serviceRegisterStore = SpringBeanUtil.getBean(ServiceRegisterStore.class);
    }
}
